package vip.xiaonuo.vein.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import vip.xiaonuo.facedoor.modular.device.entity.DeviceCategory;
import vip.xiaonuo.facedoor.modular.device.listener.DeviceChangeTypeEnum;
import vip.xiaonuo.facedoor.modular.device.listener.DevicePublisher;
import vip.xiaonuo.facedoor.modular.device.listener.DeviceSourceEnum;
import vip.xiaonuo.facedoor.modular.devicebase.entity.DeviceBase;
import vip.xiaonuo.facedoor.modular.devicebase.service.DeviceBaseService;
import vip.xiaonuo.vein.model.ResData;

import javax.annotation.Resource;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.util.Date;

@Service("HeartBeatService.class")
@Slf4j
public class HeartBeatService {

    @Resource
    private DeviceBaseService deviceBaseService;

    @Resource
    private DevicePublisher publisher;

    /**
     * 成功回复
     * @param message ws原始数据
     * @return
     */
    public String createSuccessResponse(String message){
        ResData data = ResData.success();
        return RespService.getRespStr(message,data);
    }

    public void updateDevice(String deviceNo, Session session){
        if(session==null || StringUtils.isEmpty( deviceNo)){
            return;
        }
        DeviceBase device = deviceBaseService.getOne(new LambdaQueryWrapper<DeviceBase>()
            .eq(DeviceBase :: getDeviceType, DeviceCategory.SUB_TYPE_PALM)
            .eq(DeviceBase :: getRegistrationCode, deviceNo));
        if(device!=null ){
            RemoteEndpoint.Async async = session.getAsyncRemote();
            InetSocketAddress address = (InetSocketAddress) getFieldInstance(async, "base#socketWrapper#socket#sc#remoteAddress");
            log.info("掌静脉终端地址：{}",JSON.toJSONString(address));
            device.setCabinetIp(address.getHostName());
            device.setCabinetPort(address.getPort()+"");
            device.setLastOnlineTime(new Date());
            device.setDeviceState("1");
            deviceBaseService.saveOrUpdate(device);

            publisher.publishEvent(DeviceChangeTypeEnum.EDIT, DeviceSourceEnum.BASE,device);
        }
    }


    private static Object getFieldInstance(Object obj, String fieldPath) {
        String fields[] = fieldPath.split("#");
        for (String field : fields) {
            obj = getField(obj, obj.getClass(), field);
            if (obj == null) {
                return null;
            }
        }

        return obj;
    }

    private static Object getField(Object obj, Class<?> clazz, String fieldName) {
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                Field field;
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(obj);
            } catch (Exception e) {
            }
        }
        return null;
    }


}
